import type { Ref } from 'vue'
import { unref } from 'vue'
import type { FormItemRule } from 'naive-ui'
import {
    COMMON_CHAR,
    ID_CARD,
    LETTER_NUMBER,
    REGEXP_EMAIL,
    REGEXP_PHONE,
    URL
} from '@/constants/regexp'
import type { ValidationTrigger } from 'naive-ui/es/form/src/interface'

/**
 * 是否是数字
 * @param value
 */
function isNumber(value: string | number) {
    if (typeof value === 'string' && value.trim() === '') {
        return false
    }
    return window.isNaN(Number(value)) == false
}

/**
 * 是否是整数
 * @param value
 */
function isInt(value: string | number) {
    if (typeof value === 'string' && value.trim() === '') {
        return false
    }
    if (Number.isInteger(Number(value)) == false) {
        return false
    }
    return true
}

export class Rules {
    rules: FormItemRule[] = []
    constructor() {}

    get value() {
        return this.rules
    }

    /**
     * 插入一个新的规则
     * @param rule
     */
    push(rule: FormItemRule) {
        this.rules.push(rule)
        return this
    }

    /**
     * 删除指定的第几条规则
     * @param index
     */
    delete(index: number) {
        this.rules.splice(index, 1)
    }

    /**
     * 必填
     * @param message
     * @param trigger
     */
    required(
        message: string = '不能为空',
        trigger: ValidationTrigger[] = ['input', 'blur', 'change']
    ) {
        this.rules.push({
            required: true,
            validator: (rule: FormItemRule, value: any) => {
                if (value === null || value === undefined || value === '') {
                    return new Error(message)
                }
                if (value instanceof Array && !value.length) {
                    return new Error(message)
                }
                return true
            },
            message,
            trigger
        })
        return this
    }

    /**
     * 最小长度
     * @param length
     * @param message
     * @param trigger
     */
    minLength(
        length: number,
        message: string = `长度不能小于${length}位`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                if (value.length < length) {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }

    /**
     * 最大长度
     * @param length
     * @param message
     * @param trigger
     */
    maxLength(
        length: number,
        message: string = `长度不能超过${length}位`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                if (value && value.length > length) {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }
    /**
     * 指定长度
     * @param length
     * @param message
     * @param trigger
     */
    length(
        length: number,
        message: string = `字符长度需要等于${length}位`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                if (value && value.length != length) {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }

    /**
     * 与指定值相等
     * @param compareValue
     * @param message
     * @param trigger
     */
    eq(
        compareValue: Ref<string> | string | number,
        message: string = '',
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '' || value === undefined || value === null) {
                    return true
                }
                if (value !== unref(compareValue)) {
                    return new Error(message ? message : `必须等于${unref(compareValue)}`)
                }
                return true
            },
            trigger
        })
        return this
    }

    /**
     * 大于指定值
     * @param compareValue
     * @param message
     * @param trigger
     */
    gt(
        compareValue: Ref<string> | string | number,
        message: string = '',
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '' || value === undefined || value === null) {
                    return true
                }
                const v = unref(compareValue)
                if (isNumber(value) == false || isNumber(v) == false) {
                    return new Error('请输入数字')
                }
                if (value <= v) {
                    return new Error(message ? message : `必须大于${v}`)
                }
                return true
            },
            trigger
        })
        return this
    }
    /**
     * 大于等于指定值
     * @param compareValue
     * @param message
     * @param trigger
     */
    gte(
        compareValue: Ref<string> | string | number,
        message: string = '',
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '' || value === undefined || value === null) {
                    return true
                }
                const v = unref(compareValue)
                if (isNumber(value) == false || isNumber(v) == false) {
                    return new Error('请输入数字')
                }
                if (value < v) {
                    return new Error(message ? message : `必须大于等于${v}`)
                }
                return true
            },
            trigger
        })
        return this
    }
    /**
     * 小于指定值
     * @param compareValue
     * @param message
     * @param trigger
     */
    lt(
        compareValue: Ref<string> | string | number,
        message: string = '',
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '' || value === undefined || value === null) {
                    return true
                }
                const v = unref(compareValue)
                if (isNumber(value) == false || isNumber(v) == false) {
                    return new Error('请输入数字')
                }
                if (value >= v) {
                    return new Error(message ? message : `必须小于${v}`)
                }
                return true
            },
            trigger
        })
        return this
    }
    /**
     * 小于等于指定值
     * @param compareValue
     * @param message
     * @param trigger
     */
    lte(
        compareValue: Ref<string> | string | number,
        message: string = '',
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '' || value === undefined || value === null) {
                    return true
                }
                const v = unref(compareValue)
                if (isNumber(value) == false || isNumber(v) == false) {
                    return new Error('请输入数字')
                }
                if (value > v) {
                    return new Error(message ? message : `必须小于等于${v}`)
                }
                return true
            },
            trigger
        })
        return this
    }
    /**
     * 是整数
     * @param message
     * @param trigger
     */
    _int(
        message: string = `必须是整数`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                if (isInt(value) == false) {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }

    /**
     * 正整数
     * @param message
     * @param trigger
     */
    _pint(
        message: string = `必须是正整数`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                if (isInt(value) == false) {
                    return new Error(message)
                }
                if (Number(value) <= 0) {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }

    /**
     * 自然数：0 和 正整数
     * @param message
     * @param trigger
     */
    _natural(
        message: string = `必须是大于等于0的整数`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                if (isInt(value) == false) {
                    return new Error(message)
                }
                if (Number(value) < 0) {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }

    /**
     * 数字
     * @param message
     * @param trigger
     */
    _number(
        message: string = `必须是数字`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                if (isNumber(value) == false) {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }

    /**
     * 正数
     * @param message
     * @param trigger
     */
    _pnumber(
        message: string = `必须是正数`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                if (isNumber(value) == false) {
                    return new Error(message)
                }
                if (Number(value) <= 0) {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }

    /**
     * 正数和0
     * @param message
     * @param trigger
     */
    _zpnumber(
        message: string = `必须是正数`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                if (isNumber(value) == false) {
                    return new Error(message)
                }
                if (Number(value) <= 0) {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }
    _boolean(
        message: string = `请选择`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({
            validator(rule: FormItemRule, value: string) {
                if (value === '') {
                    return true
                }
                value += ''
                if (value != '1' && value != '0' && value != 'true' && value != 'false') {
                    return new Error(message)
                }
                return true
            },
            trigger
        })
        return this
    }
    email(
        message: string = `油箱格式不正确`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({ pattern: REGEXP_EMAIL, message, trigger })
        return this
    }

    /**
     * 手机号
     * @param message
     * @param trigger
     */
    phone(
        message: string = `手机号格式不正确`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({ pattern: REGEXP_PHONE, message, trigger })
        return this
    }

    /**
     * 仅支持常见字符，包含大小写 、数字、_、 -，规则在constants/regexp中设定
     * @param message
     */
    commonChar(
        message: string = `检测到不支持的字符`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({ pattern: COMMON_CHAR, message, trigger })
        return this
    }

    idcard(
        message: string = `身份证格式不正确`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({ pattern: ID_CARD, message, trigger })
        return this
    }
    url(
        message: string = `URL格式不正确`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({ pattern: URL, message, trigger })
        return this
    }

    letterNumber(
        message: string = `仅支持字母和数字`,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({ pattern: LETTER_NUMBER, message, trigger })
        return this
    }

    regex(
        regex: RegExp,
        message: string,
        trigger: ValidationTrigger[] = ['input', 'blur']
    ) {
        this.rules.push({ pattern: regex, message, trigger })
        return this
    }
}
